home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-05-17 | 82.4 KB | 3,229 lines | [TEXT/MPS ] |
- /*
- File: FWiXcopy.c
-
- Contains: Software to handle file copies over FireWire.
-
- Version: 1.0
-
- Written by: Jay Lloyd
-
- Copyright: © 1996-1997 by Apple Computer, Inc., all rights reserved.
-
- File Ownership:
-
- DRI: Jay Lloyd
-
- Other Contact:
-
- Technology: FireWire
-
- Writers:
-
- (jkl) Jay Lloyd
-
- Change History (most recent first):
-
- <FW30> 6/19/97 jkl Changed receive notification to let the application handle the
- dialog and sound instead of notification manager. This allows
- for background processing while notification alert is displayed
- and makes playing the sound more reliable. Added a check at the
- end of HandleReceiveComplete to see if there are any pending
- send items from a send AppleScript command.
- <FW29> 6/6/97 jkl Nothing.
- <FW28> 5/28/97 jkl Changed timeout value on receive complete to account for slower
- floppy copies.
- <FW27> 5/27/97 jkl Accounted for 4 byte index at the start of each control packet.
- Changed received data handling to post the packet on the
- received data queue along with the error. Changed handle receive
- to make sure data packets get requeued on error. Made sure
- progress dialog updates when only one item is being transferred.
- <FW26> 5/16/97 jkl Corrected dialog drawing routine to not try to draw a sending
- item name if no item is being sent.
- <FW25> 5/15/97 jkl Modified error handling routines to handle errors during the
- transfer setup routines. Added error handling for a driver
- checksum routine.
- <FW24> 5/7/97 jkl Modified list structures to double linked lists to simplify
- insertion and deletion of items. Fixed an uninitialized variable
- in CheckItem. Fixed an index iterator in DirectoryBusy to make
- sure each item in the directory is checked. Set status flags
- before calling PrimeFork to prevent a case where the write
- completion would return before all of the status flags were set.
- <FW23> 4/29/97 jkl Cleaned up alerts to use global alert with filter event
- handling. Corrected check for file or file in folder busy in
- HandleCheckItem. Moved OpenDropFolder before notification
- posting in receive complete. Removed the code to zero an item's
- finder location, this was causing all of the items to be lined
- up on each other.
- <FW22> 4/8/97 jkl Cleared finder location information in the catinfo record before
- calling SetCatInfo for received items. Changed my initials.
- <FW21> 3/18/97 jkl Corrected a problem with device removal and quitting where if
- the last device in the list is getting removed, the previous
- devices next pointer did not get nilled.
- <FW20> 2/28/97 jkl Changed string length from 5 to 15 in HandleReceiveComplete to
- ensure string is long enough to display fork length and count.
- <FW19> 2/27/97 jkl Moved file conflict preferences to receiver control. Changed
- HandleReceive to continue handling packets if an error occurs
- but to only act on them if there is no error. Changed
- ReceiveComplete to send error code and fork length expected vs.
- fork length received. Removed receive timeout value since fwix
- works as a cooperative task, timing out on receive may not mean
- communication has failed, tie communications failure to control
- packets out of order.
- <FW18> 2/21/97 jkl Added AdjustNodeIcons for mulitple node management in the sender
- window.
- <FW17> 2/19/97 jkl Moved SendFileInfo to start of file transfer. Fixed a problem
- with calculating size of and deleting directories. Changed the
- node information exchange protocol to a request and reply. Fixed
- a problem with the item precheck getting out of order. Fixed a
- problem with mulitple files being sent out of order. Added
- folders to the count of items to be sent. Corrected a problem
- with received packets fields being cleared by file system calls.
- Added the name of the item in the same name alert. Made the
- replace option the default in the same name alert. Corrected a
- problem with the receive folder being located on a volume other
- than the boot volume.
- <FW16> 2/14/97 jkl Corrected a problem with sending items that are not on the
- default volume.
- <FW15> 2/13/97 jkl Extended communication failure timeout values. During
- simultaneous file transfers or starting to send a large number
- of items, communications could stall long enough to make the
- timers incorrectly go off.
- <FW14> 2/13/97 jkl Added ForkWriteComplete flag to FWWrite complete routine to make
- sure a data buffer will be available to start reading next file
- fork. Changed FSClose calls to PBClose. Fixed queueing problem
- in HandleReceive.
- <FW13> 2/11/97 jkl Added support for read control and data packets. Read data
- packets are passed to asynch file write routine.
- <FW12> 2/10/97 ES Cleaned up deallocation code.
- <FW11> 2/2/97 jkl Modified send check and receive check routines to use control
- queue. Modified communications timeout values to allow receiver
- more time to respond to sent items. Corrected timeout errors
- during receive that were invalid by making sure a receive is in
- progress. Corrected menu enabled/disabled states.
- <FW10> 1/29/97 ES Changed HandleFileReadComplete and HandleFileWriteComplete to
- return noErr to work around bug in the File Manager.
- <FW9> 1/27/97 ES Added FW control PB queue so that start/end folder/fork, etc.
- commands aren't queued with fork data packets. This fixes a case
- where we'd run out of PBs for control commands which would halt
- transmission.
- <FW8> 1/27/97 jkl Added timer routines to check for a file transfer communications
- break. Added sendflags to handle item exists preferences. Added
- a send precheck to get status of receive end. Added unique
- file/folder name creation. Handled deleting folders properly by
- removing all folder contents first.
- <FW7> 1/16/97 jkl Added user interface features for alpha candidate. Added file
- receive notification. Changed node info packet handling to
- display node icon.
- <FW6> 1/8/97 ES Changed to use FWX nodes instead of FWX drivers.
- <FW5> 11/13/96 jkl Multiple machine support. Node names. Transfer stop. CallDriver
- interface instead of DoDriverIO.
- <FW5> 11/7/96 jkl Fixed folder copies. Added multiple machine support.
- Added stop transfer functionality. Added receive node
- name support.
- <FW4> 11/5/96 ES Fixed dequeue reentrancy bug.
- <FW3> 10/31/96 jkl Added support for sending/receiving multiple files/
- folders. Cleaned up copy progress dialog.
- <FW2> 10/16/96 jkl For sending a file:
- Modified queue handling to use OS Utils interrupt
- safe queue routines. Broke the send file and
- handle fork read complete routines into smaller
- subroutines. Each subroutine and completion routine
- makes their own calls to the file system and firewire
- driver instead of queueing the requests to be sent
- later. The ioMisc field of the parameter block
- holds the packet type.
- For receiving:
- The FireWire read completion routine only queues
- the data for later processing. It does not make
- another read. All of the available read parameter
- blocks are already on the driver read queue. The
- read parameter blocks are queued for another read
- after they are handled in the received data routine.
- Broke the receive routine into smaller subroutines.
- The ioMisc field of the parameter block holds the
- packet type. If a file already exists in the drop folder
- it is now just overwritten -- easier testing.
- <FW1> 10/2/96 jkl initial check-in
-
- */
-
- #include <Files.h>
- #include <Folders.h>
- #include <Errors.h>
- #include <Dialogs.h>
- #include <Script.h>
- #include <Devices.h>
- #include <Timer.h>
- #include <TextUtils.h>
- #include <Resources.h>
- #include <Sound.h>
-
- #include "FWiX.h"
- #include "FWiXmain.h"
- #include "FWiXdrag.h"
-
- #include <stdio.h>
- extern char debugStr[256];
- static pascal void FWDebugStr(
- ConstStr255Param debuggerMsg)
- {
- #ifdef FW_DEBUG_BUILD
- #if FW_DEBUG_BUILD
- DebugStr (debuggerMsg);
- #endif
- #endif
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // Internal procedure prototypes.
- //
-
- OSErr HandleFSItem (
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID);
-
- static OSErr SendTxCheck(
- FWXNodeID recvNodeID,
- NodeSendItemPtr pSendItem);
-
- OSErr SendFSItem (
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID,
- Boolean startSend);
-
- static OSErr SendAFolder(
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID);
-
- static OSErr QueueFolderItems(
- FSSpecPtr pFolderSpec,
- FWXNodeID recvNodeID);
-
- static OSErr SendFolderInfo(
- FSSpecPtr pFSItem);
-
- static OSErr SendAFile (
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID);
-
- static OSErr SendStartFolder (
- ConstStr255Param pFileName);
-
- static OSErr SendFileInfo (
- CInfoPBPtr pCatInfo);
-
- static OSErr SendEndFolder (void);
-
- static OSErr SendStartFile (
- ConstStr255Param pFileName);
-
- static OSErr SendStartFork(
- UInt32 length,
- UInt32 whichFork);
-
- static OSErr PrimeAFork (
- SInt16 forkRefNum);
-
- static OSErr SendEndFork(
- UInt32 whichFork);
-
- void HandleForkReadComplete (void);
-
- static OSErr FinishSendFile (void);
-
- void HandleReceive (void);
-
- static OSErr HandleReceiveComplete(
- FWXNodeID recvNode,
- UInt32 result,
- UInt32 forkLength,
- UInt32 lengthRecvd);
-
- static OSErr HandlePreflightReply(
- FWXNodeID sendingNodeID,
- SInt32 itemSize,
- ConstStr255Param itemName);
-
- static Boolean DirectoryBusy (
- SInt32 dirID);
-
- static OSErr HandleCheckItem(
- CurFileInfoPtr pCurFileInfo,
- FWXNodeID sendingNodeID,
- UInt32 itemSize,
- ConstStr255Param itemName);
-
- static OSErr SendReceiveComplete(
- OSErr sendError,
- FWXNodeID senderID,
- UInt32 forkLegnth,
- UInt32 recvCount,
- ConstStr255Param itemName);
-
- static OSErr HandleStartFolder(
- ConstStr255Param folderName,
- SInt32 *curDirID);
-
- static OSErr CreateUniqueFolder(
- ConstStr255Param fileName,
- FSSpecPtr pFileSpec,
- SInt32 *dirID);
-
- static OSErr DeleteDirectoryContents (
- SInt32 dirID);
-
- static OSErr DeleteDirectory (
- FSSpecPtr pDirSpec);
-
- static OSErr DeleteFile(
- SInt16 vRefNum,
- SInt32 dirID,
- StringPtr fName);
-
- static OSErr HandleStartFile(
- ConstStr255Param fileName,
- CurFileInfoPtr pCurFileInfo);
-
- static OSErr CreateUniqueFile(
- ConstStr255Param fileName,
- FSSpecPtr pFileSpec,
- SInt32 dirID);
-
- static OSErr HandleStartFork(
- IOParamPtr pb,
- UInt32 forkLength,
- SInt16 refNum);
-
- static OSErr HandleForkData(
- IOParamPtr pb,
- SInt16 refNum);
-
- OSErr HandleStopTransfer(
- CurFileInfoPtr pCurFileInfo);
-
- static OSErr HandleEndFolder(
- SInt32 *curDirID);
-
- static OSErr HandleNodeInfoRequest(
- ConstStr255Param nodeName,
- FWXNodeID nodeID);
-
- static OSErr HandleNodeInfoReply(
- ConstStr255Param nodeName,
- FWXNodeID nodeID);
-
- static void CleanupTxError(
- RecvNodePtr pNode);
-
- static OSErr HandleNodeQuit(
- FWXNodeID nodeID);
-
- static OSErr HandleFolderInfo(
- CInfoPBPtr pCatInfoPB,
- SInt32 curDirID);
-
- static OSErr HandleFileInfo(
- FSSpecPtr pNewFileSpec,
- CInfoPBPtr pCatInfoPB);
-
- static OSErr AddItemToQueue (
- HFileInfo *pFileInfo,
- FSSpecPtr pFSItem,
- Boolean isFile);
-
- OSErr FSpGetCatInfo (
- FSSpec *fsSpec,
- CInfoPBPtr result);
-
- void CleanupCopyDialog(
- WindowPtr theDialog);
-
- static OSErr DisplayCopyDialog (void);
-
- pascal void DrawProgressBar(
- WindowPtr theWindow,
- SInt16 itemNo);
-
- void UpdateProgressBar(
- WindowPtr theWindow,
- SInt16 itemNo);
-
- static OSErr CalcDirectorySize (
- SInt32 dirID,
- SInt16 vRefNum,
- UInt32 *dirSize,
- UInt32 *dirItems);
-
- OSErr GetItemSize (
- NodeSendItemPtr pSendItem);
-
- OSErr CountCopyData (
- FSSpec *pFSSpec);
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // External procedure prototypes
- //
-
- extern OSErr GetNodeInfo (
- FWXNodeID nodeID,
- RecvNodePtr *pRecvNode);
-
- extern OSErr SendFWXInfo (
- FWXNodeID nodeID,
- UInt32 sendType);
-
- extern OSErr InitRecvNode (
- FWXNodeID nodeID,
- ConstStr255Param nodeName);
-
- extern void OpenDropFolder (void);
-
- extern pascal void HandleReplyTimeout (
- MyTMTaskPtr pTMTask);
-
- extern void AdjustNodeIcons (
- WindowDataPtr pWinData,
- Rect *windRect);
-
- extern OSErr AdjustScrollBars (
- WindowPtr pWin,
- Boolean adjustSizes);
-
- extern void StopTransfer (
- RecvNodePtr pNode);
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // Globals
- //
- UInt32 gBytesToCopy;
- UInt32 gBytesCopied;
- UInt32 gItemsToCopy;
- CInfoPBRec gCatInfoPB; // used in directory traversal to help recursion
-
- extern FWXAppDataPtr gpFWXAppData;
- extern QHdr gSendQHdr;
- extern QHdr gAESendQHdr;
- extern QHdr gReceiveQHdr;
- extern QHdr gFileReadQHdr;
- extern QHdr gFWControlQHdr;
- extern QHdr gCurFileQHdr;
- extern SInt16 gCurForkRefNum;
-
-
- extern Boolean gSendingFile,
- gCheckingTransfer,
- gSendingDataFork,
- gSendingResFork,
- gForkWriteComplete,
- gForkComplete;
-
- extern FWXNodeID gReceiveError;
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleFSItem
- //
- // Called for each item dropped on a node icon. There will be two lists, one
- // for items that need to be checked if ok to send (size, name, etc.) and the
- // other for items waiting to be sent.
- //
- // Add the item to the receive node's checking for ok to transfer list and see
- // if the receive node can handle this item.
- //
- OSErr HandleFSItem (
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID)
- {
- RecvNodePtr pRecvNode;
- NodeSendItemPtr pCheckItem;
- NodeSendItemPtr pTempCheckItem;
- OSErr err;
-
- if (gpFWXAppData->pSenderWindow == FrontWindow())
- {
- DisplayCopyDialog();
- gCheckingTransfer = true;
- }
-
- // get a pointer to the node record
- err = GetNodeInfo(recvNodeID, &pRecvNode);
- if (err == noErr)
- {
- // add the item to the node's send list
- pCheckItem = (NodeSendItemPtr) NewPtrClear(sizeof(NodeSendItem));
- if (pCheckItem == nil)
- return memFullErr;
- pCheckItem->sendItemSpec = *pFSItem;
-
- if (pRecvNode->pTxItemList == nil)
- {
- // first item in the list
- pRecvNode->pTxItemList = pCheckItem;
- }
- else
- {
- // traverse the list and add this item to the end
- pTempCheckItem = pRecvNode->pTxItemList;
- while (pTempCheckItem->pNextSendItem != nil)
- {
- pTempCheckItem = pTempCheckItem->pNextSendItem;
- }
- pTempCheckItem->pNextSendItem = pCheckItem;
- pCheckItem->pPreviousSendItem = pTempCheckItem;
- }
- // JKL *** need to put a timer on this call to cancel send if no response.
- err = SendTxCheck(recvNodeID, pCheckItem);
- }
- return err;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // SendTxCheck
- //
- // Send a packet with item name and size to receive node for a check
- // of item exists and space ok.
- //
- static OSErr SendTxCheck(
- FWXNodeID recvNodeID,
- NodeSendItemPtr pCheckItem)
- {
- IOParamPtr pIOPb;
- FWXPacketPtr pPktInfo;
- OSErr err = noErr;
-
- err = GetItemSize(pCheckItem);
- if (err != noErr)
- {
- sprintf(debugStr, "SendTxCheck, error in GetItemSize: %d", err);
- FWDebugStr((ConstStr255Param) c2pstr (debugStr));
- }
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil)
- {
- SetupFWControlPB(pIOPb);
- // SetupFWControlPB will leave an invalid node id in nameptr at this point
- pIOPb->ioNamePtr = (StringPtr) recvNodeID;
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kPreflightCopy;
- pIOPb->ioMisc = (Ptr) kPreflightCopy;
- pPktInfo->packetData = (Ptr) pCheckItem->itemSize;
-
- BlockMove(pCheckItem->sendItemSpec.name, ((Ptr) &pPktInfo->packetData) + 4,
- pCheckItem->sendItemSpec.name[0] + 1);
- pIOPb->ioReqCount = pCheckItem->sendItemSpec.name[0] + 1 + 4 + 4; // length of string plus packet header plus size
-
- err = CallFWXNode(pIOPb);
- }
- else
- {
- err = qErr;
- FWDebugStr("\pNo buffer for SendTxCheck");
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendFSItem
- //
- // Called for each item dropped on a node icon once the item has been
- // OK'd to send. Add the item to the transfer queue. If there is no
- // transfer under way and all pending items are on the send queue, start sending.
- //
- OSErr SendFSItem (
- FSSpecPtr pFSItem, // the file or folder to add to the queue
- FWXNodeID recvNodeID, // the receiver's id
- Boolean readyToSend) // true when all pending items are on the queue
- {
- GrafPtr curPort;
- DialogPtr pDialog;
- CInfoPBRec catInfoPB;
- TxFSSpecPtr pTxItem;
- Handle hItem;
- Rect r;
- SInt16 itemType;
- OSErr err;
- Boolean isFile;
-
- err = CountCopyData(pFSItem);
- if (err != noErr)
- {
- sprintf(debugStr, "SendFSItem, error in CountCopyData: %d", err);
- FWDebugStr((ConstStr255Param) c2pstr (debugStr));
- }
- err = FSpGetCatInfo(pFSItem, &catInfoPB);
- if (err == noErr)
- {
- isFile = !(catInfoPB.dirInfo.ioFlAttrib & ioDirMask);
-
- pTxItem = (TxFSSpecPtr) NewPtr(sizeof(TxFSSpec));
- if (pTxItem != nil)
- {
- pTxItem->recvNode = recvNodeID;
- pTxItem->pFSSpec = (FSSpecPtr) NewPtr(sizeof(FSSpec));
- if (pTxItem->pFSSpec != nil)
- {
- *(pTxItem->pFSSpec) = *pFSItem;
- if (isFile)
- pTxItem->itemType = kFileInfo;
- else
- pTxItem->itemType = kStartFolder;
- Enqueue((QElemPtr) pTxItem, &gSendQHdr);
-
- } else err = memFullErr;
- } else err = memFullErr;
-
- if ((err == noErr) && !gSendingFile && readyToSend)
- {
- gCheckingTransfer = false;
- gSendingFile = true;
- gBytesCopied = 0;
- pDialog = FrontWindow();
- GetDialogItem(pDialog, kProgressPrompt, &itemType, &hItem, &r);
- SetDialogItemText(hItem, "\pSending: ");
-
- // force dialog update
- GetPort(&curPort);
- SetPort(pDialog);
- InvalRect(&pDialog->portRect);
- SetPort(curPort);
-
-
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- if (pTxItem != nil)
- {
- if (pTxItem->itemType == kFileInfo)
- SendAFile(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kStartFolder)
- SendAFolder(pTxItem->pFSSpec, pTxItem->recvNode);
- }
- }
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendAFolder
- //
- // Handle sending a folder. Add each item in the folder to the transfer
- // queue and an end folder item. Send the folder info. Send each item in
- // the folder.
- //
- static OSErr SendAFolder(
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID)
- {
- QElemPtr restOfQueue;
- QElemPtr curQTail;
- TxFSSpecPtr pTxItem;
- OSErr err;
-
- // save a pointer to the rest of the queue
- // the rest of the queue is reattached after the folders' items
- restOfQueue = gSendQHdr.qHead->qLink;
- gSendQHdr.qHead->qLink = nil;
- curQTail = gSendQHdr.qTail;
-
- // handle special case of only one item in queue
- if (curQTail == gSendQHdr.qHead)
- curQTail = nil;
- gSendQHdr.qTail = gSendQHdr.qHead;
-
- err = QueueFolderItems(pFSItem, recvNodeID);
-
- // add end folder queue element
- pTxItem = (TxFSSpecPtr) NewPtr(sizeof(TxFSSpec));
- if (pTxItem != nil)
- {
- pTxItem->itemType = kEndFolder;
- pTxItem->recvNode = recvNodeID;
- Enqueue((QElemPtr) pTxItem, &gSendQHdr);
- }
- else
- err = memFullErr;
-
- gSendQHdr.qTail->qLink = restOfQueue;
- if (curQTail != nil)
- gSendQHdr.qTail = curQTail;
-
- SendStartFolder(pFSItem->name);
- SendFolderInfo(pFSItem);
-
- // dequeue and dispose of folder queue entry
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- Dequeue((QElemPtr) pTxItem, &gSendQHdr);
- DisposePtr((Ptr) pTxItem->pFSSpec);
- DisposePtr((Ptr) pTxItem);
-
- // get another queue item
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- if (pTxItem != nil) {
- if (pTxItem->itemType == kFileInfo)
- SendAFile(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kStartFolder)
- SendAFolder(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kEndFolder)
- SendEndFolder();
-
- } else {
- gSendingFile = false;
-
- // toss the progress bar
- CleanupCopyDialog(FrontWindow());
- }
-
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // QueueFolderItems
- //
- // Traverse a folder, adding each of its items to the transmit queue.
- //
- static OSErr QueueFolderItems(
- FSSpecPtr pFolderSpec,
- FWXNodeID recvNodeID)
- {
- TxFSSpecPtr pTxItem;
- CInfoPBRec catInfoPB;
- Str63 fileNameBuffer;
- UInt32 dirID;
- SInt16 index;
- OSErr err = noErr;
- Boolean isFile;
-
- err = FSpGetCatInfo(pFolderSpec, &catInfoPB);
- catInfoPB.hFileInfo.ioNamePtr = fileNameBuffer;
-
- if (err == noErr)
- {
- dirID = catInfoPB.dirInfo.ioDrDirID;
-
- for (index = 1; ; index++)
- {
- // reset the directory id after each call to PBGetCatInfo
- catInfoPB.hFileInfo.ioDirID = dirID;
- catInfoPB.hFileInfo.ioFDirIndex = index;
-
- err = PBGetCatInfoSync(&catInfoPB);
- if (err)
- {
- // returns file not found when directory has been traversed
- if (err == fnfErr)
- err = noErr;
- break;
- }
-
- isFile = !(catInfoPB.dirInfo.ioFlAttrib & ioDirMask);
-
- // create queue entry
- pTxItem = (TxFSSpecPtr) NewPtr(sizeof(TxFSSpec));
- if (pTxItem == nil)
- {
- err = memFullErr;
- break;
- }
-
- // create fsspec for queue entry
- pTxItem->pFSSpec = (FSSpecPtr) NewPtr(sizeof(FSSpec));
- if (pTxItem->pFSSpec == nil)
- {
- err = memFullErr;
- break;
- }
-
- // fill in fsspec fields
- pTxItem->pFSSpec->vRefNum = pFolderSpec->vRefNum;
- pTxItem->pFSSpec->parID = dirID;
- BlockMove(fileNameBuffer,pTxItem->pFSSpec->name,fileNameBuffer[0]+1);
-
- // fill in other queue element fields
- pTxItem->recvNode = recvNodeID;
- if (isFile)
- pTxItem->itemType = kFileInfo;
- else
- pTxItem->itemType = kStartFolder;
- Enqueue((QElemPtr) pTxItem, &gSendQHdr);
- }
- }
-
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendAFile
- //
- // Start sending a file to another firewire node. Send start file
- // packet with the file name, send start data fork packet with
- // fork size. If there is no data fork, send start resource packet
- // with fork size. Prime the send fork routine. The rest of the file
- // send will complete as the PBRead of the file forks completes.
- //
- static OSErr SendAFile(
- FSSpecPtr pFSItem,
- FWXNodeID recvNodeID)
- {
- CInfoPBRec catInfoPB;
- UInt32 forkLength;
- OSErr err;
-
- err = FSpGetCatInfo(pFSItem, &catInfoPB);
- if (err == noErr)
- err = SendStartFile((ConstStr255Param) pFSItem->name);
-
- if (err == noErr)
- err = SendFileInfo(&catInfoPB);
-
- if (err == noErr)
- {
- forkLength = catInfoPB.hFileInfo.ioFlLgLen;
- if (forkLength != 0)
- {
- err = SendStartFork(forkLength, kStartDataFork);
- if (err == noErr)
- {
- err = FSpOpenDF(pFSItem, fsRdPerm, &gCurForkRefNum);
- if (err == noErr)
- {
- gSendingDataFork = true;
- gForkComplete = false;
- gForkWriteComplete = false;
- err = PrimeAFork(gCurForkRefNum);
- if (err != noErr)
- {
- gSendingDataFork = false;
- gForkComplete = true;
- gForkWriteComplete = true;
- }
- }
- }
- }
- else
- {
- // data fork empty, start sending resource fork
- forkLength = catInfoPB.hFileInfo.ioFlRLgLen;
- if (forkLength != 0)
- {
- err = SendStartFork(forkLength, kStartResFork);
- if (err == noErr)
- {
- err = FSpOpenRF(pFSItem, fsRdPerm, &gCurForkRefNum);
- if (err == noErr)
- {
- gSendingResFork = true;
- gForkComplete = false;
- gForkWriteComplete = false;
- err = PrimeAFork(gCurForkRefNum);
- if (err != noErr)
- {
- gSendingResFork = false;
- gForkComplete = true;
- gForkWriteComplete = true;
- }
- }
- }
- }
- else
- {
- // no data in the file at all
- err = FinishSendFile();
- }
- }
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendStartFolder
- //
- // Send the start folder packet with the folder name
- //
- static OSErr SendStartFolder(
- ConstStr255Param pFolderName)
- {
- FWXPacketPtr pPktInfo; // points to ioBuffer
- IOParamPtr pIOPb; // a parameter block for reading
- OSErr err = noErr;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil) {
- SetupFWControlPB(pIOPb);
-
- // copy the file name into the data buffer for start file packet
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kStartFolder;
- pIOPb->ioMisc = (Ptr) kStartFolder;
- BlockMove(pFolderName, &pPktInfo->packetData, pFolderName[0]+1);
- pIOPb->ioReqCount = pFolderName[0] + 1 + 4; // length of name plus packet header
-
- err = CallFWXNode(pIOPb);
-
- } else {
- err = qErr;
- FWDebugStr("\pNo buffer for start folder");
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendEndFolder
- //
- // Send end folder packet
- //
- static OSErr SendEndFolder(void)
- {
- IOParamPtr pIOPb; // a queue record
- FWXPacketPtr pPktInfo;
- TxFSSpecPtr pTxItem;
- OSErr err;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil) {
- SetupFWControlPB(pIOPb);
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kEndFolder;
- pIOPb->ioMisc = (Ptr) kEndFolder;
- pIOPb->ioReqCount = 4;
-
- err = CallFWXNode(pIOPb);
-
- } else {
- err = qErr;
- FWDebugStr("\pNo buffer, SendEndFolder");
- }
-
- // dequeue and dispose of end folder queue entry
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- Dequeue((QElemPtr) pTxItem, &gSendQHdr);
- DisposePtr((Ptr) pTxItem);
- gItemsToCopy--;
-
- // get another queue item
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- if (pTxItem != nil) {
- if (pTxItem->itemType == kFileInfo)
- SendAFile(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kStartFolder)
- SendAFolder(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kEndFolder)
- SendEndFolder();
-
- } else {
- gSendingFile = false;
-
- // toss the progress bar
- CleanupCopyDialog(FrontWindow());
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendFolderInfo
- //
- // Send the folder catalog info
- //
- static OSErr SendFolderInfo(
- FSSpecPtr pFSItem)
- {
- IOParamPtr pIOPb; // a queue record
- FWXPacketPtr pPktInfo;
- OSErr err;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil)
- {
- SetupFWControlPB(pIOPb);
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kFolderInfo;
- pIOPb->ioMisc = (Ptr) kFolderInfo;
- pIOPb->ioReqCount = sizeof(CInfoPBRec) + 4; // catalog info plus packet header
-
- err = FSpGetCatInfo(pFSItem, (CInfoPBPtr) &pPktInfo->packetData);
-
- if (err == noErr)
- err = CallFWXNode(pIOPb);
- }
- else
- {
- err = qErr;
- FWDebugStr("\pNo buffer, SendFolderInfo");
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendStartFile
- //
- // Send the start file packet including the file name
- //
- static OSErr SendStartFile(
- ConstStr255Param pFileName)
- {
- FWXPacketPtr pPktInfo; // points to ioBuffer
- IOParamPtr pIOPb; // a parameter block for reading
- OSErr err = noErr;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil) {
- SetupFWControlPB(pIOPb);
-
- // copy the file name into the data buffer for start file packet
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kStartFile;
- pIOPb->ioMisc = (Ptr) kStartFile;
- BlockMove(pFileName, (Ptr) &pPktInfo->packetData, pFileName[0]+1);
- pIOPb->ioReqCount = pFileName[0] + 1 + 4; // length of name plus packet header plus flags
-
- err = CallFWXNode(pIOPb);
-
- } else {
- err = qErr;
- FWDebugStr("\pNo buffer for start file");
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendStartFork
- //
- // Send a start fork packet including fork length
- //
- static OSErr SendStartFork(
- UInt32 length,
- UInt32 whichFork)
- {
- FWXPacketPtr pPktInfo; // puts a packet structure on ioBuffer
- IOParamPtr pIOPb; // a parameter block for writing
- OSErr err = noErr;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil) {
- SetupFWControlPB(pIOPb);
-
- // copy fork length into start fork packet
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = whichFork;
- pIOPb->ioMisc = (Ptr) whichFork;
- pPktInfo->packetData = (Ptr) length;
- pIOPb->ioReqCount = 4 + 4; // packet header + fork length
-
- err = CallFWXNode(pIOPb);
-
- } else {
- err = qErr;
- FWDebugStr("\pNo buffer for start fork");
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // PrimeAFork
- //
- // Set up fork transfer, will be completed elsewhere.
- // This routine does not set the packet type. Have to do that in read
- // completion.
- //
- static OSErr PrimeAFork(
- SInt16 forkRefNum)
- {
- IOParamPtr pPB; // IO parameter block
- OSErr anErr = noErr;
-
- FWIXDequeue ((QElemPtr *) &pPB, &gFileReadQHdr);
- if (pPB != nil) {
- // set file pos to start
- pPB->ioRefNum = forkRefNum;
- pPB->ioPosMode = fsFromStart;
- pPB->ioPosOffset = 0;
- anErr = PBSetFPosSync((ParmBlkPtr) pPB);
- if (anErr != noErr)
- return anErr;
-
- // do the read
- SetupFileReadPB(pPB);
- anErr = PBReadAsync((ParmBlkPtr) pPB);
-
- } else {
- anErr = qErr;
- FWDebugStr("\pNo buffer for prime fork");
- }
-
- return anErr;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendEndFork
- //
- // Send the end fork packet
- //
- static OSErr SendEndFork(
- UInt32 whichFork)
- {
- FWXPacketPtr pPktInfo; // puts a packet structure on ioBuffer
- IOParamPtr pIOPb; // write parameter block
- OSErr err = noErr;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil) {
- SetupFWControlPB(pIOPb);
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = whichFork;
- pIOPb->ioMisc = (Ptr) whichFork;
- pIOPb->ioReqCount = 4; // just packet header
-
- err = CallFWXNode(pIOPb);
-
- } else {
- FWDebugStr("\pNo buffer for end fork");
- err = qErr;
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleFileReadComplete
- //
- // Completion routine for PBRead from file. Send the read data to the firewire
- // node.
- //
- pascal OSErr HandleFileReadComplete(
- ParmBlkPtr pFilePB)
- {
- IOParamPtr pb; // parameter block to issue another read
- OSErr ioResult;
-
- ioResult = pFilePB->ioParam.ioResult;
-
- if ((ioResult == noErr) || (ioResult == eofErr)) {
-
- if (ioResult == eofErr)
- gForkComplete = true;
-
- if (pFilePB->ioParam.ioActCount != 0)
- {
- // send the read packet to the FireWire node
- pFilePB->ioParam.ioMisc = (Ptr) kForkData;
- pFilePB->ioParam.ioReqCount = pFilePB->ioParam.ioActCount;
- gBytesCopied += pFilePB->ioParam.ioActCount;
- SetupFWWritePB((IOParamPtr) pFilePB);
-
- CallFWXNode((IOParamPtr) pFilePB);
- }
- else
- {
- // no data in the packet, just queue it back to the read quueue
- Enqueue((QElemPtr) pFilePB, &gFileReadQHdr);
- }
-
- if (ioResult == noErr)
- {
- // there is more data, do another read
- FWIXDequeue ((QElemPtr *) &pb, &gFileReadQHdr);
- if (pb != nil)
- {
- SetupFileReadPB(pb);
- PBReadAsync((ParmBlkPtr) pb);
- }
- }
- }
- else
- {
- sprintf(debugStr, "Error in PBRead from file: %hd", pFilePB->ioParam.ioResult);
- FWDebugStr((ConstStr255Param) c2pstr (debugStr));
- Enqueue((QElemPtr) pFilePB, &gFileReadQHdr);
- }
-
- return (noErr);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleForkReadComplete
- //
- // Called at idle time, after a file's fork has been read. If sending data
- // fork then start sending resource fork. If sending resource fork, finish
- // sending file.
- //
- void HandleForkReadComplete(void)
- {
- CInfoPBRec catInfoPB;
- ParamBlockRec pb;
- TxFSSpecPtr pTxItem;
- UInt32 forkLength;
- OSErr err = noErr;
-
- pb.ioParam.ioRefNum = gCurForkRefNum;
- err = PBCloseSync(&pb);
-
- if (gSendingDataFork)
- {
- gSendingDataFork = false;
- err = SendEndFork(kEndDataFork);
-
- // start sending the resource fork, if there is one
-
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- err = FSpGetCatInfo(pTxItem->pFSSpec, &catInfoPB);
- if (err == noErr)
- {
- forkLength = catInfoPB.hFileInfo.ioFlRLgLen;
- if (forkLength != 0)
- {
- err = SendStartFork(forkLength, kStartResFork);
-
- if (err == noErr)
- {
- err = FSpOpenRF(pTxItem->pFSSpec, fsRdPerm, &gCurForkRefNum);
- if (err == noErr)
- {
- gSendingResFork = true;
- gForkComplete = false;
- gForkWriteComplete = false;
- err = PrimeAFork(gCurForkRefNum);
- if (err != noErr)
- {
- gSendingResFork = false;
- gForkComplete = true;
- gForkWriteComplete = true;
- }
- } // end if error in open resource fork
- } // end if error in send start fork
- }
- else
- {
- // no resource fork, finished sending file
- err = FinishSendFile();
- }
- } // end if error in getcatinfo
-
- } else if (gSendingResFork) {
- gSendingResFork = false;
- err = SendEndFork(kEndResFork);
-
- if (err == noErr)
- err = FinishSendFile();
- }
-
- if (err != noErr) {
- sprintf(debugStr, "Error in ForkReadComplete: %hd", err);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendFileInfo
- //
- // Send the finder catalog info for a file.
- //
- static OSErr SendFileInfo (
- CInfoPBPtr pCatInfo)
- {
- IOParamPtr pIOPb; // a queue record
- FWXPacketPtr pPktInfo;
- OSErr err;
-
- // send catalog information
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil)
- {
- SetupFWControlPB(pIOPb);
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kFileInfo;
- pIOPb->ioMisc = (Ptr) kFileInfo;
- pIOPb->ioReqCount = sizeof(CInfoPBRec) + 4; // catalog info plus packet header
- BlockMove(pCatInfo, &pPktInfo->packetData, sizeof(CInfoPBRec));
-
- err = CallFWXNode(pIOPb);
- }
- else
- {
- err = qErr;
- FWDebugStr("\pNo buffer, SendCatInfo");
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // FinishSendFile
- //
- // Send the file info and clean up after file transfer
- //
- static OSErr FinishSendFile(void)
- {
- IOParamPtr pIOPb; // a queue record
- FWXPacketPtr pPktInfo;
- TxFSSpecPtr pTxItem;
- FWXNodeID txNode;
- RecvNodePtr pTxNodeInfo;
- OSErr err;
-
- // send end file
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil)
- {
- SetupFWControlPB(pIOPb);
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kEndFile;
- pIOPb->ioMisc = (Ptr) kEndFile;
- pIOPb->ioReqCount = 4;
-
- err = CallFWXNode(pIOPb);
- }
- else
- {
- err = qErr;
- FWDebugStr("\pNo buffer, SendEndFile");
- }
-
- // dequeue and dispose of file queue entry
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- txNode = pTxItem->recvNode; // save the node id for primetime
- Dequeue((QElemPtr) pTxItem, &gSendQHdr);
- DisposePtr((Ptr) pTxItem->pFSSpec);
- DisposePtr((Ptr) pTxItem);
- gItemsToCopy--;
-
- // get another queue item
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- if (pTxItem != nil)
- {
- if (pTxItem->itemType == kFileInfo)
- SendAFile(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kStartFolder)
- SendAFolder(pTxItem->pFSSpec, pTxItem->recvNode);
- else if (pTxItem->itemType == kEndFolder)
- SendEndFolder();
- }
- else
- {
- gSendingFile = false;
-
- err = GetNodeInfo(txNode, &pTxNodeInfo);
- if (err == noErr)
- {
- pTxNodeInfo->pReplyTimer->nodeID = txNode;
- PrimeTime((QElemPtr) pTxNodeInfo->pReplyTimer, 10000); // set for 10 seconds
- } // JKL ***, need to work with this value
-
- // toss the progress bar
- CleanupCopyDialog(FrontWindow());
- }
- return err;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleFWWriteComplete
- //
- // Completion routine for PBWrite to FireWire node.
- // If there is a file fork currently being read, make a read with the
- // completed parameter block.
- //zzz HandleFWWriteComplete, pFWPB, gFileReadQHdr, FWIXDequeue, and SetupFileReadPB
- //zzz must all be held.
- //
- void HandleFWWriteComplete(
- IOParamPtr pFWPB)
- {
- IOParamPtr pb; // parameter block for doing another read
-
- if (pFWPB->ioResult == noErr) {
-
- // queue the completed parameter block
- Enqueue((QElemPtr) pFWPB, &gFileReadQHdr);
-
- // if we are still sending file data, issue another read
- if (!gForkComplete)
- {
- FWIXDequeue ((QElemPtr *) &pb, &gFileReadQHdr);
- if (pb != nil)
- {
- SetupFileReadPB(pb);
- PBReadAsync((ParmBlkPtr) pb);
- }
- }
- else if (gSendingDataFork || gSendingResFork)
- gForkWriteComplete = true;
- }
- else
- {
- sprintf(debugStr, "Error in PBWrite to FWiX Node: %hd", pFWPB->ioResult);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- Enqueue((QElemPtr) pFWPB, &gFileReadQHdr);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleFWControlComplete
- //
- // Completion routine for PBWrite control data to FireWire node.
- //zzz HandleFWControlComplete, pFWPB, and gFWControlQHdr must all be held.
- //
- void HandleFWControlComplete(
- IOParamPtr pFWPB)
- {
- // queue the completed parameter block
- Enqueue((QElemPtr) pFWPB, &gFWControlQHdr);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleFWReadComplete
- //
- // Completion routine for PBRead to FireWire node. If the paramblock does
- // not contain any data, we assume it is cleaning up and dispose of the
- // paramblock. Otherwise queue the param block and let the receive routine handle it.
- //zzz HandleFWReadComplete, pFWPB, and gReceiveQHdr must all be held.
- //
- void HandleFWReadComplete(
- IOParamPtr pFWReadPb)
- {
- // JKL *** kind of a hack, the only way ioActCount should be
- // 0 is after a close call to close the node and clean up
- // any read requests. In that case the completion routine
- // will be called at normal execution time, so dispose of the buffers
- if (pFWReadPb->ioActCount == 0)
- {
- UnholdMemory(pFWReadPb->ioBuffer, pFWReadPb->ioReqCount);
- DisposePtr(pFWReadPb->ioBuffer);
- UnholdMemory((Ptr) pFWReadPb, sizeof(IOParam));
- DisposePtr((Ptr) pFWReadPb);
- }
- else
- {
- Enqueue((QElemPtr) pFWReadPb, &gReceiveQHdr);
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleReceive
- //
- // Process parameter blocks in the receive buffer. For files, create it
- // and a static FSSpec record to be used throughout the routine. Open each
- // fork as it comes, presetting eof for the fork. As fork data is received
- // copy it into a filewrite buffer, once the buffer is full, write the data.
- // Keep processing received data if there is any on the queue. Make another
- // read to the node as parameter block is handled. The idle routine
- // will call this again if the file is not completed. For folders, create
- // the folder and update the current directory id, write the folder info,
- // and once each of the folder's items are copied, set the current
- // directory id to the folder's parent
- //
-
- void HandleReceive(void)
- {
- FWXPacketPtr pRecvPacket; // format the received data with our packet fields
- IOParamPtr pPB; // firewire read parameter block
- CurFileInfoPtr pCurFileInfo; // Active file for a driver ID
- FWXNodeID senderNodeID; // node that sent the data
- SndListHandle hSound; // notification sound
- UInt32 packetType; // what kind of data is in packet
- SInt16 curAttributes;
- OSErr err;
-
- pPB = (IOParamPtr) gReceiveQHdr.qHead;
- senderNodeID = (FWXNodeID) pPB->ioNamePtr;
- err = GetCurFileInfo(senderNodeID, &pCurFileInfo, true);
- pCurFileInfo->curError = err;
-
- while (pPB != nil)
- {
- Dequeue((QElemPtr) pPB, &gReceiveQHdr);
- pRecvPacket = (FWXPacketPtr) pPB->ioBuffer;
- packetType = (UInt32) pPB->ioMisc;
-
- if (senderNodeID != (FWXNodeID) pPB->ioNamePtr)
- {
- senderNodeID = (FWXNodeID) pPB->ioNamePtr;
- err = GetCurFileInfo(senderNodeID, &pCurFileInfo, true);
- pCurFileInfo->curError = err;
- }
-
- // catch any FireWire receive errors here.
- if (pCurFileInfo->curError == noErr)
- pCurFileInfo->curError = pPB->ioResult;
-
- if (pPB->ioResult != noErr)
- pCurFileInfo->curError = pPB->ioResult;
-
- switch (packetType)
- {
- case kStartFile:
- pCurFileInfo->curError = noErr;
- err = HandleStartFile ((ConstStr255Param) &pRecvPacket->packetData, // file name
- pCurFileInfo);
- break;
-
- case kStartDataFork:
- if (pCurFileInfo->curError == noErr)
- {
- err = FSpOpenDF(pCurFileInfo->pCurFileSpec, fsWrPerm, &pCurFileInfo->curFileRefNum);
- pCurFileInfo->recvLength = 0;
- pCurFileInfo->forkLength = (UInt32) pRecvPacket->packetData;
- if (err == noErr)
- err = HandleStartFork(pPB, pCurFileInfo->forkLength, pCurFileInfo->curFileRefNum);
- }
- break;
-
- case kStartResFork:
- if (pCurFileInfo->curError == noErr)
- {
- err = FSpOpenRF(pCurFileInfo->pCurFileSpec, fsWrPerm, &pCurFileInfo->curFileRefNum);
- pCurFileInfo->recvLength = 0;
- pCurFileInfo->forkLength = (UInt32) pRecvPacket->packetData;
- if (err == noErr)
- err = HandleStartFork(pPB, pCurFileInfo->forkLength, pCurFileInfo->curFileRefNum);
- }
- break;
-
- case kForkData:
- if (pCurFileInfo->curError == noErr)
- {
- pCurFileInfo->recvLength += pPB->ioActCount;
- err = HandleForkData(pPB, pCurFileInfo->curFileRefNum);
- }
- else
- {
- // return packet to data buffer queue
- pPB->ioTrap = kFWXRead;
- pPB->ioCompletion = (IOCompletionUPP) HandleFWReadComplete;
- pPB->ioReqCount = kFWReadDataBufSize;
- pPB->ioMisc = (Ptr) kForkData;
- CallFWXNode(pPB);
- }
- break;
-
- case kEndDataFork:
- case kEndResFork:
- if (pCurFileInfo->curError == noErr)
- {
- pPB->ioRefNum = pCurFileInfo->curFileRefNum;
- err = PBCloseSync((ParmBlkPtr) pPB);
- if (pCurFileInfo->recvLength != pCurFileInfo->forkLength)
- err = ioErr;
- }
- break;
-
- case kFileInfo:
- if (pCurFileInfo->curError == noErr)
- {
- err = HandleFileInfo (pCurFileInfo->pCurFileSpec,
- (CInfoPBPtr) &pRecvPacket->packetData);
- }
- break;
-
- case kEndFile:
- FlushVol(nil, 0);
- break;
-
- case kStartFolder:
- pCurFileInfo->curError = noErr;
- err = HandleStartFolder ((ConstStr255Param) &pRecvPacket->packetData, // folder name
- &(pCurFileInfo->curDirID));
- break;
-
- case kFolderInfo:
- if (pCurFileInfo->curError == noErr)
- {
- err = HandleFolderInfo ((CInfoPBPtr) &pRecvPacket->packetData,
- pCurFileInfo->curDirID);
- }
- break;
-
- case kEndFolder:
- HandleEndFolder (&pCurFileInfo->curDirID);
- break;
-
- case kNodeInfoRequest:
- err = HandleNodeInfoRequest ((ConstStr255Param) &pRecvPacket->packetData,
- senderNodeID);
- break;
-
- case kNodeInfoReply:
- err = HandleNodeInfoReply ((ConstStr255Param) &pRecvPacket->packetData,
- senderNodeID);
- break;
-
- case kQuitNotify:
- err = HandleNodeQuit (senderNodeID);
- break;
-
- case kTransferStopped:
- err = HandleStopTransfer (pCurFileInfo);
- break;
-
- case kPreflightCopy:
- err = HandleCheckItem (pCurFileInfo,
- senderNodeID,
- (UInt32) pRecvPacket->packetData,
- (ConstStr255Param) (((Ptr) &pRecvPacket->packetData) + 4));
- break;
-
- case kPreflightReply:
- err = HandlePreflightReply (senderNodeID,
- (SInt32) pRecvPacket->packetData,
- (ConstStr255Param) (((Ptr) &pRecvPacket->packetData) + 4));
- break;
-
- case kReceiveReply:
- err = HandleReceiveComplete (senderNodeID,
- (UInt32) pRecvPacket->packetData, // error code
- *((UInt32 *) (pPB->ioBuffer + 12)), // fork length
- *((UInt32 *) (pPB->ioBuffer + 16))); // bytes received
- break;
-
- default:
- err = paramErr;
- break;
- }
-
- // update current error state if previous state was no error
- if (pCurFileInfo->curError == noErr)
- pCurFileInfo->curError = err;
-
- if (err != noErr)
- {
- sprintf(debugStr, "Error in handle receive: %hd", err); // JKL *** handle this error
- FWDebugStr((ConstStr255Param) c2pstr (debugStr));
- }
-
- if (packetType != kForkData)
- {
- // nil the misc field so fwxread knows its a control packet
- pPB->ioTrap = kFWXRead;
- pPB->ioReqCount = kFWReadControlBufSize;
- pPB->ioCompletion = (IOCompletionUPP) HandleFWReadComplete;
- pPB->ioMisc = nil;
- CallFWXNode(pPB);
- }
-
- if ((packetType == kEndFile) || (packetType == kEndFolder) ||
- (packetType == kStartFile) || (packetType == kStartFolder))
- {
- if (pCurFileInfo->curError != noErr)
- {
- SendReceiveComplete (pCurFileInfo->curError,
- senderNodeID,
- pCurFileInfo->forkLength,
- pCurFileInfo->recvLength,
- pCurFileInfo->pCurFileSpec->name);
- // JKL *** delete the file or folder if it exists,
- // for now we leave it for debugging purposes
- }
- }
- pPB = (IOParamPtr) gReceiveQHdr.qHead;
- }
-
- // JKL *** Need to have some type of start transaction/end transaction code. Its possible
- // that the endfile or endfolder message would be that last on the current queue but not
- // the last file or folder in the entire send. This would do the notification too early.
- if ((packetType == kEndFile) || (packetType == kEndFolder))
- {
- SendReceiveComplete (pCurFileInfo->curError,
- senderNodeID,
- pCurFileInfo->forkLength,
- pCurFileInfo->recvLength,
- pCurFileInfo->pCurFileSpec->name);
- if (err == noErr)
- {
- if (gpFWXAppData->fwixPrefs & kNotifyOpen)
- OpenDropFolder();
- if (gpFWXAppData->fwixPrefs & kNotifyFlash)
- {
- if (gpFWXAppData->pNotifyRec->nmRefCon == kNoNotificationPosted)
- {
- gpFWXAppData->pNotifyRec->nmRefCon = kNotificationPosted;
- NMInstall(gpFWXAppData->pNotifyRec);
- }
- }
- if (gpFWXAppData->fwixPrefs & kNotifySound)
- {
- hSound = (SndListHandle) GetNamedResource('snd ', gpFWXAppData->fwixNotifySound);
- if (hSound != nil)
- {
- curAttributes = GetResAttrs((Handle) hSound);
- if (curAttributes & resPurgeable)
- HNoPurge((Handle) hSound);
- SndPlay(nil, hSound, false);
- SetResAttrs((Handle) hSound, curAttributes);
- ReleaseResource((Handle) hSound);
- }
- }
- if (gpFWXAppData->fwixPrefs & kNotifyAlert)
- HandleNoteAlert(kReceiveAlertID);
- }
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleReceiveComplete
- //
- // Display an error if the transfer does not complete.
- //
- static OSErr HandleReceiveComplete(
- FWXNodeID recvNode,
- UInt32 result,
- UInt32 forkLength,
- UInt32 lengthRecvd)
- {
- RecvNodePtr pRecvNodeInfo;
- AESendRecPtr pAESendElem;
- Str31 s;
- OSErr err;
-
- err = GetNodeInfo(recvNode, &pRecvNodeInfo);
- if (err == noErr)
- {
- RmvTime((QElemPtr) pRecvNodeInfo->pReplyTimer);
- pRecvNodeInfo->pReplyTimer->timerTask.tmWakeUp = 0;
- pRecvNodeInfo->pReplyTimer->timerTask.tmReserved = 0;
- InsTime((QElemPtr) pRecvNodeInfo->pReplyTimer);
-
- if (result != noErr)
- {
- if (result == ioErr)
- {
- NumToString((forkLength - lengthRecvd), s);
- ParamText(s, "\p", "\p", "\p");
- HandleCautionAlert(kIOErrorAlertID);
- }
- else if (result == fBsyErr)
- {
- HandleCautionAlert(kItemBusyErrAlertID);
- }
- else
- {
- NumToString(result, s);
- ParamText(s, "\p", "\p", "\p");
- HandleCautionAlert(kRecvErrorAlertID);
- }
- }
- }
-
- if (!(gSendingFile || gCheckingTransfer))
- {
- pAESendElem = (AESendRecPtr) gAESendQHdr.qHead;
- if (pAESendElem != nil)
- {
- Dequeue((QElemPtr) pAESendElem, &gAESendQHdr);
- SendFSSpecListToSelf(pAESendElem->recvNode, pAESendElem->pSendItemsList, pAESendElem->numSendItems);
- DisposePtr((Ptr) pAESendElem->pSendItemsList);
- DisposePtr((Ptr) pAESendElem);
- }
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandlePreflightReply
- //
- // Take care of the reply to the send check. This is a long one. If there is
- // an error from the reply, handle it according to error level or user set
- // preference. If item is going to be sent, have to remove it from the
- // send check list and put it on the transfer queue. If it is the last checked
- // item, then tell senditems to start going.
- //
- static OSErr HandlePreflightReply(
- FWXNodeID receiveNodeID,
- SInt32 preflightResult,
- ConstStr255Param itemName)
- {
- RecvNodePtr pRecvNode;
- NodeSendItemPtr pSendItem, pTempItem;
- UInt32 index;
- UInt32 itemCount;
- OSErr err;
- Boolean okToSend = true;
-
- // get a pointer to the node record
- err = GetNodeInfo(receiveNodeID, &pRecvNode);
- if (err == noErr) {
- ParamText(itemName, pRecvNode->nodeName, "\p", "\p");
-
- // check for errors and handle them according to prefs
- // if not enough space or unknown error, clear list and
- // show alert, if file exists error, handle according to
- // prefs
- if (preflightResult != 0) {
- switch (preflightResult)
- {
- case kSpaceError:
- StopTransfer(pRecvNode);
- HandleStopAlert(kSpaceErrAlertID);
- okToSend = false;
- break;
- case kItemExistsError:
- StopTransfer(pRecvNode);
- HandleStopAlert(kItemExistsErrAlertID);
- okToSend = false;
- break;
- case fBsyErr:
- StopTransfer(pRecvNode);
- HandleStopAlert(kItemBusyErrAlertID);
- okToSend = false;
- break;
- case nsvErr:
- StopTransfer(pRecvNode);
- HandleStopAlert(kNSVErrAlertID);
- okToSend = false;
- break;
- default:
- StopTransfer(pRecvNode);
- HandleStopAlert(kUnknownErrAlertID);
- okToSend = false;
- break;
- }
- }
-
- if (okToSend)
- {
- // find the send item record in the list, dequeue it and call sendfsitem,
- // if this is the last item record, tell sendfsitem to start sending
- pSendItem = pRecvNode->pTxItemList;
- if (pSendItem == nil)
- {
- err = resNotFound;
- }
- else
- {
- // traverse the list looking for the item name
- itemCount = 1;
- while (pSendItem->pNextSendItem != nil)
- {
- // find the item record that matches the name
- if (EqualString(itemName, pSendItem->sendItemSpec.name, true, true))
- break;
- pSendItem = pSendItem->pNextSendItem;
- itemCount++;
- }
-
- // now have to remove the item from the list
- if (itemCount == 1)
- {
- pRecvNode->pTxItemList = pSendItem->pNextSendItem;
- }
- else
- {
- // traverse the list finding the item before this one
- // set its next pointer to the found item's next pointer
- pTempItem = pRecvNode->pTxItemList;
- for (index = 2; index < itemCount; index++)
- pTempItem = pTempItem->pNextSendItem;
- pTempItem->pNextSendItem = pSendItem->pNextSendItem;
- }
-
- // now add the item to the send list then delete it
- // if this is the last item in the list, start the send
- if (pRecvNode->pTxItemList == nil)
- SendFSItem(&pSendItem->sendItemSpec, receiveNodeID, true);
- else
- SendFSItem(&pSendItem->sendItemSpec, receiveNodeID, false);
- DisposePtr((Ptr) pSendItem);
- }
- }
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // CleanupTxError
- //
- // Clean up send lists on error.
- //
- static void CleanupTxError(
- RecvNodePtr pNode)
- {
- NodeSendItemPtr pSendItem, pTempItem;
- TxFSSpecPtr pTxItem;
-
- pSendItem = pNode->pTxItemList;
- if (pSendItem != nil)
- {
- do
- {
- pTempItem = pSendItem;
- pSendItem = pSendItem->pNextSendItem;
- DisposePtr((Ptr) pTempItem);
- } while (pSendItem != nil);
- }
- pNode->pTxItemList = nil;
-
- // clear the transfer list, dequeue and dispose of file queue entry
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- while (pTxItem != nil)
- {
- Dequeue((QElemPtr) pTxItem, &gSendQHdr);
- DisposePtr((Ptr) pTxItem->pFSSpec);
- DisposePtr((Ptr) pTxItem);
-
- // get another queue item
- pTxItem = (TxFSSpecPtr) gSendQHdr.qHead;
- }
- gItemsToCopy = 0;
- gBytesToCopy = 0;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // DirectoryBusy
- //
- // Check to see if a file in the directory to be deleted is in use or locked.
- //
- static Boolean DirectoryBusy (
- SInt32 dirID)
- {
- Str32 fName;
- UInt32 savedDir;
- SInt16 index;
- OSErr err;
- Boolean isFolder;
- Boolean isBusy = false;
-
- index = 0;
- do {
- gCatInfoPB.dirInfo.ioDrDirID = dirID;
- index++;
- gCatInfoPB.dirInfo.ioFDirIndex = index;
- gCatInfoPB.dirInfo.ioNamePtr = fName;
- err = PBGetCatInfoSync(&gCatInfoPB);
- if (err == noErr)
- {
- savedDir = dirID;
- isFolder = gCatInfoPB.dirInfo.ioFlAttrib & ioDirMask;
- if (isFolder)
- {
- savedDir = gCatInfoPB.dirInfo.ioDrDirID;
- err = DeleteDirectoryContents(gCatInfoPB.dirInfo.ioDrDirID);
- gCatInfoPB.dirInfo.ioNamePtr = nil;
- }
- if (err == noErr)
- {
- gCatInfoPB.dirInfo.ioDrDirID = savedDir;
- if (!isFolder)
- isBusy = gCatInfoPB.hFileInfo.ioFlAttrib & 0x80;
- }
- }
- } while ((err == noErr) && (!isBusy));
-
- if (err == fnfErr)
- err = noErr;
-
- return isBusy;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleCheckItem
- //
- // Check to see if we can safely receive the pending item.
- //
- static OSErr HandleCheckItem(
- CurFileInfoPtr pCurFileInfo,
- FWXNodeID sendingNodeID,
- UInt32 itemSize,
- ConstStr255Param itemName)
- {
- CInfoPBRec catInfo;
- HParamBlockRec pb;
- IOParamPtr pIOPb;
- FWXPacketPtr pPktInfo;
- SInt32 checkResult;
- OSErr makeErr = noErr,
- sizeErr = noErr,
- err;
- Boolean itemExists = false,
- itemBusy = false,
- sizeOK = false;
-
- err = InitRecvFolder(&pCurFileInfo->curDirID);
- if (err == noErr)
- {
- // check for item exists
- makeErr = FSMakeFSSpec (gpFWXAppData->fwixReceiveFolder.vRefNum,
- pCurFileInfo->curDirID,
- itemName,
- pCurFileInfo->pCurFileSpec);
- if (makeErr == noErr)
- {
- // item exists, set flag according to prefs
- if (gpFWXAppData->fwixPrefs & kConflictCancel)
- itemExists = true;
- else if (gpFWXAppData->fwixPrefs & kConflictOverwrite)
- {
- err = FSpGetCatInfo(pCurFileInfo->pCurFileSpec, &catInfo);
- if (err == noErr)
- {
- if (catInfo.dirInfo.ioFlAttrib & ioDirMask)
- itemBusy = DirectoryBusy(catInfo.dirInfo.ioDrDirID);
- else
- itemBusy = catInfo.hFileInfo.ioFlAttrib & 0x80;
- }
- }
- }
- else if (makeErr == fnfErr)
- makeErr = noErr;
-
- // check item size
- if (makeErr == noErr)
- {
- pb.volumeParam.ioVRefNum = pCurFileInfo->pCurFileSpec->vRefNum;
- pb.volumeParam.ioNamePtr = nil;
- pb.volumeParam.ioVolIndex = 0;
-
- sizeErr = PBHGetVInfoSync(&pb);
- if (sizeErr == noErr)
- sizeOK = (pb.volumeParam.ioVFrBlk * pb.volumeParam.ioVAlBlkSiz) > itemSize;
- }
- }
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil)
- {
- SetupFWControlPB(pIOPb);
- // SetupFWControlPB will leave an invalid node id in nameptr at this point
- pIOPb->ioNamePtr = (StringPtr) sendingNodeID;
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kPreflightReply;
- pIOPb->ioMisc = (Ptr) kPreflightReply;
- checkResult = 0;
- if (err)
- checkResult = err;
- else if (!sizeOK)
- checkResult = kSpaceError;
- else if (itemExists)
- checkResult = kItemExistsError;
- else if (itemBusy)
- checkResult = fBsyErr;
- if (makeErr || sizeErr)
- checkResult = kUnknownError;
-
- pPktInfo->packetData = (Ptr) checkResult;
- BlockMove(itemName, ((Ptr) &pPktInfo->packetData) + 4, itemName[0] + 1);
- pIOPb->ioReqCount = itemName[0] + 1 + 4 + 4; // length of string plus packet header plus size
-
- err = CallFWXNode(pIOPb);
- }
- else
- {
- err = qErr;
- FWDebugStr("\pNo buffer for PreflightReply");
- }
-
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SendReceiveComplete
- //
- // Send a receive notification to the sending machine.
- //
- static OSErr SendReceiveComplete (
- OSErr sendError,
- FWXNodeID senderID,
- UInt32 forkLength,
- UInt32 recvCount,
- ConstStr255Param name)
- {
- IOParamPtr pIOPb;
- FWXPacketPtr pPktInfo;
- OSErr err;
-
- FWIXDequeue ((QElemPtr *) &pIOPb, &gFWControlQHdr);
- if (pIOPb != nil)
- {
- SetupFWControlPB(pIOPb);
- // SetupFWControlPB will leave an invalid node id in nameptr at this point
- pIOPb->ioNamePtr = (StringPtr) senderID;
-
- pPktInfo = (FWXPacketPtr) pIOPb->ioBuffer;
- pPktInfo->packetType = kReceiveReply;
- pIOPb->ioMisc = (Ptr) kReceiveReply;
-
- pPktInfo->packetData = (Ptr) sendError;
- ((UInt32 *) pIOPb->ioBuffer)[3] = forkLength;
- ((UInt32 *) pIOPb->ioBuffer)[4] = recvCount;
- BlockMove(name, ((Ptr) &pPktInfo->packetData) + 12, name[0]+1);
- pIOPb->ioReqCount = 16 + name[0] + 1; // length of header plus error plus two fork counts
-
- err = CallFWXNode(pIOPb);
- }
- else
- {
- err = qErr;
- FWDebugStr("\pNo buffer for SendReceiveReply");
- }
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // GetCurFileInfo
- //
- // Scan the received file queue for an entry matching the node id.
- // Return the pointer to the file info, create one if not found. Make
- // sure the drop folder exists and set receive directory id to it.
- //
- // JKL ***, when do we dispose of this
- //
-
- OSErr GetCurFileInfo(
- FWXNodeID sourceID,
- CurFileInfoPtr *hCurFileInfo,
- Boolean createNew)
- {
- CurFileInfoPtr temp;
- OSErr err = noErr;
-
- temp = (CurFileInfoPtr) gCurFileQHdr.qHead;
- while ((temp != nil) && (temp->curFileSenderID != sourceID))
- temp = (CurFileInfoPtr) temp->qLink;
-
- if ((temp == nil) && createNew)
- {
- temp = (CurFileInfoPtr) NewPtrClear(sizeof (CurFileInfo));
- if (temp == nil)
- return memFullErr;
-
- temp->pCurFileSpec = (FSSpecPtr) NewPtr(sizeof(FSSpec));
- if (temp->pCurFileSpec == nil)
- {
- DisposePtr((Ptr) temp);
- return memFullErr;
- }
-
- temp->curFileSenderID = sourceID;
- err = InitRecvFolder(&temp->curDirID);
- temp->curError = noErr;
- Enqueue((QElemPtr) temp, &gCurFileQHdr);
- }
-
- if ((temp == nil) && (!createNew))
- err = resNotFound; // JKL *** what error?
- *hCurFileInfo = temp;
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // InitRecvFolder
- //
- // Create the receive folder if it does not exist.
- //
-
- OSErr InitRecvFolder(
- SInt32 *dirID)
- {
- CInfoPBRec catInfo;
- OSErr err;
-
- err = FSpGetCatInfo(&(gpFWXAppData->fwixReceiveFolder), &catInfo);
- if (err != noErr) {
- err = FSpDirCreate(&(gpFWXAppData->fwixReceiveFolder), smSystemScript, dirID);
- } else {
- *dirID = catInfo.dirInfo.ioDrDirID;
- }
-
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleStopTransfer
- //
- // Take care of transfer being stopped, close any open fork, requeue param
- // block. Delete the current item. Clear receive queue. Reset receive directory
- // id to top level of drop folder.
- //
-
- OSErr HandleStopTransfer(
- CurFileInfoPtr pCurFileInfo)
- {
- IOParamPtr pPB; // firewire read parameter block
- ParamBlockRec pb;
- OSErr err = noErr;
-
- if (pCurFileInfo->curFileRefNum != 0)
- {
- pb.ioParam.ioRefNum = pCurFileInfo->curFileRefNum;
- err = PBCloseSync(&pb);
- pCurFileInfo->curFileRefNum = 0;
- }
-
- // delete current item, JKL *** if item is a folder, what to do?
- FSpDelete(pCurFileInfo->pCurFileSpec);
-
- pPB = (IOParamPtr) gReceiveQHdr.qHead;
- while (pPB != nil)
- {
- Dequeue((QElemPtr) pPB, &gReceiveQHdr);
-
- // take all of the received packets off the queue and send them
- // back to the driver
- CallFWXNode(pPB);
- pPB = (IOParamPtr) gReceiveQHdr.qHead;
- }
-
- // reset current directory if
- InitRecvFolder(&pCurFileInfo->curDirID);
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleEndFolder
- //
- // Set the receive folder directory to the current directory's parent
- //
- static OSErr HandleEndFolder(
- SInt32 *curDirID)
- {
- FSSpec curFolderSpec;
- OSErr err;
-
- err = FSMakeFSSpec (gpFWXAppData->fwixReceiveFolder.vRefNum,
- *curDirID,
- nil,
- &curFolderSpec);
- *curDirID = curFolderSpec.parID;
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleNodeInfoRequest
- //
- // If the nodeName has not been received yet, store it in the node record
- // force a window update, and send our nodeName to the source node.
- //
- static OSErr HandleNodeInfoRequest(
- ConstStr255Param nodeName,
- FWXNodeID nodeID)
- {
- RecvNodePtr pRecvNode;
- GrafPtr pWindowPort;
- OSErr err = noErr;
-
- err = GetNodeInfo(nodeID, &pRecvNode);
- if (err == resNotFound)
- {
- // init the new node
- err = InitRecvNode(nodeID, nodeName);
-
- ShowWindow(gpFWXAppData->pSenderWindow);
- pWindowPort = (GrafPtr) GetWindowPort(gpFWXAppData->pSenderWindow);
- SetPortWindowPort(pWindowPort);
- InvalRect(&(pWindowPort->portRect));
- EnableItem(GetMenuHandle(kFileMenuID), kCloseMenuItem);
- EnableItem(GetMenuHandle(kViewMenuID), 0);
- DrawMenuBar();
- }
-
- err = SendFWXInfo(nodeID, kNodeInfoReply);
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleNodeInfoReply
- //
- // If the nodeName has not been received yet, store it in the node record
- // and force a window update.
- //
- static OSErr HandleNodeInfoReply(
- ConstStr255Param nodeName,
- FWXNodeID nodeID)
- {
- RecvNodePtr pRecvNode;
- GrafPtr pWindowPort;
- OSErr err = noErr;
-
- err = GetNodeInfo(nodeID, &pRecvNode);
- if (err == resNotFound)
- {
- // init the new node
- err = InitRecvNode(nodeID, nodeName);
-
- ShowWindow(gpFWXAppData->pSenderWindow);
- pWindowPort = (GrafPtr) GetWindowPort(gpFWXAppData->pSenderWindow);
- SetPortWindowPort(pWindowPort);
- InvalRect(&(pWindowPort->portRect));
- EnableItem(GetMenuHandle(kFileMenuID), kCloseMenuItem);
- EnableItem(GetMenuHandle(kViewMenuID), 0);
- DrawMenuBar();
- }
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleNodeQuit
- //
- // Take care of a fwix node quitting, clean up window and node record.
- //
- static OSErr HandleNodeQuit(
- FWXNodeID nodeID)
- {
- WindowDataPtr pWinData;
- RecvNodePtr pRecvNode;
- Boolean foundNodeID;
- OSErr err = noErr;
-
- if (gSendingFile || gCheckingTransfer)
- {
- if (nodeID == ((TxFSSpecPtr) gSendQHdr.qHead)->recvNode)
- {
- err = GetNodeInfo(nodeID, &pRecvNode);
- if (err == noErr)
- StopTransfer(pRecvNode);
- HandleStopAlert(kReceiverQuitAlertID);
- }
- }
-
- foundNodeID = false;
- pWinData = (WindowDataPtr) GetWRefCon(gpFWXAppData->pSenderWindow);
- pRecvNode = pWinData->pRecvNodeList;
- do
- {
- if (pRecvNode->nodeID == nodeID)
- {
- foundNodeID = true;
- break;
- }
- pRecvNode = pRecvNode->pNextNode;
-
- } while ((pRecvNode != nil) && !foundNodeID);
-
- // Remove the node from the receive node list.
- if (foundNodeID)
- {
- // remove the node from the list
- if (pRecvNode->pNextNode != nil)
- pRecvNode->pNextNode->pPreviousNode = pRecvNode->pPreviousNode;
-
- if (pRecvNode->pPreviousNode != nil)
- pRecvNode->pPreviousNode->pNextNode = pRecvNode->pNextNode;
- else
- pWinData->pRecvNodeList = pRecvNode->pNextNode;
-
- if (pRecvNode->pReplyTimer != nil)
- {
- if (pRecvNode->pReplyTimer->timerTask.tmAddr != nil)
- DisposeRoutineDescriptor(pRecvNode->pReplyTimer->timerTask.tmAddr);
- DisposePtr((Ptr) pRecvNode->pReplyTimer);
- }
- DisposePtr((Ptr) pRecvNode);
- pWinData->numRecvNodes--;
-
- if (pWinData->numRecvNodes == 0)
- {
- HideWindow(gpFWXAppData->pSenderWindow);
- DisableItem(GetMenuHandle(kFileMenuID), kOpenMenuItem);
- DisableItem(GetMenuHandle(kFileMenuID), kCloseMenuItem);
- DisableItem(GetMenuHandle(kViewMenuID), 0);
- DrawMenuBar();
- }
- else
- {
- // Force an update
- AdjustNodeIcons (pWinData, &gpFWXAppData->pSenderWindow->portRect);
- AdjustScrollBars (gpFWXAppData->pSenderWindow, false);
- InvalRect (&gpFWXAppData->pSenderWindow->portRect);
- }
- }
-
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleStartFolder
- //
- // Create the new folder and update receive folder directory id
- //
- static OSErr HandleStartFolder(
- ConstStr255Param folderName,
- SInt32 *curDirID)
- {
- FSSpec newFolderSpec;
- OSErr err;
-
- err = FSMakeFSSpec (gpFWXAppData->fwixReceiveFolder.vRefNum,
- *curDirID,
- folderName,
- &newFolderSpec);
- if (err != noErr)
- {
- if (err == fnfErr) // should get fnfErr for new folder
- err = FSpDirCreate(&newFolderSpec, smSystemScript, curDirID);
- else
- return err; // some other type of error, whoa!
- }
- else
- {
- // folder exists, handle it according to preferences
- if (gpFWXAppData->fwixPrefs & kConflictRename)
- CreateUniqueFolder(folderName, &newFolderSpec, curDirID);
- else if (gpFWXAppData->fwixPrefs & kConflictOverwrite)
- {
- err = DeleteDirectory(&newFolderSpec);
- if (err == noErr)
- err = FSpDirCreate(&newFolderSpec, smSystemScript, curDirID);
- }
- else
- return kItemExistsError;
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // DeleteDirectory
- //
- // Delete a directory by removing all of its contents and then it.
- //
- static OSErr DeleteDirectory (
- FSSpecPtr pFolderSpec)
- {
- CInfoPBRec catInfoPB;
- OSErr err;
-
- gCatInfoPB.dirInfo.ioVRefNum = pFolderSpec->vRefNum;
- FSpGetCatInfo(pFolderSpec, &catInfoPB);
- err = DeleteDirectoryContents(catInfoPB.dirInfo.ioDrDirID);
- if (err == noErr)
- err = FSpDelete(pFolderSpec);
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // DeleteDirectoryContents
- //
- // Delete a directory's contents by deleting each item in the folder.
- //
- static OSErr DeleteDirectoryContents(
- SInt32 dirID)
- {
- Str32 fName;
- UInt32 savedDir;
- OSErr err;
- Boolean isFolder;
-
- do {
- gCatInfoPB.dirInfo.ioDrDirID = dirID;
- gCatInfoPB.dirInfo.ioFDirIndex = 1;
- gCatInfoPB.dirInfo.ioNamePtr = fName;
- err = PBGetCatInfoSync(&gCatInfoPB);
- if (err == noErr)
- {
- savedDir = dirID;
- isFolder = gCatInfoPB.dirInfo.ioFlAttrib & ioDirMask;
- if (isFolder)
- {
- savedDir = gCatInfoPB.dirInfo.ioDrDirID;
- err = DeleteDirectoryContents(gCatInfoPB.dirInfo.ioDrDirID);
- gCatInfoPB.dirInfo.ioNamePtr = nil;
- }
- if (err == noErr)
- {
- gCatInfoPB.dirInfo.ioDrDirID = savedDir;
- err = PBHDeleteSync((HParmBlkPtr) &gCatInfoPB);
- }
- }
- } while (err == noErr);
-
- if (err == fnfErr)
- err = noErr;
-
- return err;
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // DeleteFile
- //
- // DeleteFile is called by the DeleteDirecotry to remove a single file.
- //
- static OSErr DeleteFile(
- SInt16 vRefNum,
- SInt32 dirID,
- StringPtr fName)
- {
- HParamBlockRec pBlock;
- OSErr err;
-
- pBlock.ioParam.ioVRefNum = vRefNum;
- pBlock.ioParam.ioNamePtr = fName;
- pBlock.fileParam.ioDirID = dirID;
-
- err = PBHDelete(&pBlock,false);
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // CreateUniqueFolder
- //
- // Add a suffix to the folder to make it unique.
- // Return the new directory id for receives.
- //
- static OSErr CreateUniqueFolder(
- ConstStr255Param folderName,
- FSSpecPtr pFolderSpec,
- SInt32 *dirID)
- {
- Str32 newName; // not sure how big our name buffer is
- // so copy it to a new one
- UInt32 nameIndex;
- UInt8 nameSuffix[4];
- UInt8 endX;
- OSErr err = noErr;
-
- endX = folderName[0] + 1;
- if (endX > 27) // can only have 31 characters, leave some padding
- endX = 27;
- BlockMove(folderName, newName, endX);
- newName[endX] = '-';
- endX++;
- nameIndex = 1;
- do {
- NumToString(nameIndex, nameSuffix);
- BlockMove(nameSuffix + 1, newName + endX, nameSuffix[0]);
- newName[0] = endX + nameSuffix[0] - 1;
- err = FSMakeFSSpec (gpFWXAppData->fwixReceiveFolder.vRefNum,
- *dirID,
- newName,
- pFolderSpec);
- nameIndex++;
- } while (err == noErr);
- if (err == fnfErr)
- err = FSpDirCreate(pFolderSpec, smSystemScript, dirID);
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleStartFile
- //
- // Create a file system spec for the current file record. Create the file.
- //
-
- static OSErr HandleStartFile(
- ConstStr255Param fileName,
- CurFileInfoPtr pCurFileInfo)
- {
- OSErr err = noErr;
-
- // JKL *** need to handle the user trashing the drop folder
- err = FSMakeFSSpec (gpFWXAppData->fwixReceiveFolder.vRefNum,
- pCurFileInfo->curDirID,
- fileName,
- pCurFileInfo->pCurFileSpec);
- if (err != noErr)
- {
- if (err == fnfErr) // should get fnfErr for new file
- err = FSpCreate(pCurFileInfo->pCurFileSpec, 0, 0, smSystemScript);
- else
- return err; // some other type of error, whoa!
- }
- else
- {
- // file exists, handle it according to preferences
- if (gpFWXAppData->fwixPrefs & kConflictRename)
- {
- err = CreateUniqueFile(fileName, pCurFileInfo->pCurFileSpec, pCurFileInfo->curDirID);
- }
- else if (gpFWXAppData->fwixPrefs & kConflictOverwrite)
- {
- // delete the file and create a new one
- err = FSpDelete (pCurFileInfo->pCurFileSpec);
- if (err == noErr)
- err = FSpCreate (pCurFileInfo->pCurFileSpec, 0, 0, smSystemScript);
- } else
- err = kItemExistsError;
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // CreateUniqueFile
- //
- // Add a suffix to the filename to make it unique
- //
- static OSErr CreateUniqueFile(
- ConstStr255Param fileName,
- FSSpecPtr pFileSpec,
- SInt32 dirID)
- {
- Str32 newName; // not sure how big our fileName buffer is
- // so copy it to a new one
- UInt32 nameIndex;
- UInt8 nameSuffix[4];
- UInt8 endX;
- OSErr err = noErr;
-
- endX = fileName[0] + 1;
- if (endX > 27) // can only have 31 characters, leave some padding
- endX = 27;
- BlockMove(fileName, newName, endX);
- newName[endX] = '-';
- endX++;
- nameIndex = 1;
- do {
- NumToString(nameIndex, nameSuffix);
- BlockMove(nameSuffix + 1, newName + endX, nameSuffix[0]);
- newName[0] = endX + nameSuffix[0] - 1;
- err = FSMakeFSSpec (gpFWXAppData->fwixReceiveFolder.vRefNum,
- dirID,
- newName,
- pFileSpec);
- nameIndex++;
- } while (err == noErr);
- if (err == fnfErr)
- err = FSpCreate(pFileSpec, 0, 0, smSystemScript);
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleStartFork
- //
- // Open and pre-allocate file fork
- //
- static OSErr HandleStartFork(
- IOParamPtr pb,
- UInt32 forkLength,
- SInt16 refNum)
- {
- OSErr err = noErr;
-
- if (err == noErr)
- {
- pb->ioRefNum = refNum;
- pb->ioMisc = (Ptr) forkLength;
- err = PBSetEOFSync((ParmBlkPtr) pb);
- if (err != noErr)
- return err;
-
- // reset fork mark to start of file
- pb->ioPosMode = fsFromStart;
- pb->ioPosOffset = 0;
- err = PBSetFPosSync((ParmBlkPtr) pb);
- if (err != noErr)
- return err;
- }
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleForkData
- //
- // Writes data to the file using an existing parameter block. If the existing parameter
- // block is full, a new one is created.
- //
- //
- static OSErr HandleForkData(
- IOParamPtr pb,
- SInt16 refNum)
- {
- OSErr err = noErr;
-
- pb->ioRefNum = refNum;
- pb->ioPosMode = fsAtMark + 0x0020;
- pb->ioReqCount = pb->ioActCount;
- pb->ioActCount = 0;
- pb->ioCompletion = gpFWXAppData->fileWriteCompletionHandler;
-
- err = PBWriteAsync((ParmBlkPtr) pb);
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleFileWriteComplete
- //
- // Completion routine for PBWrite to file.
- // Issue a read to the FireWire driver with the parameter block.
- //
- pascal OSErr HandleFileWriteComplete(
- ParmBlkPtr pFilePB)
- {
- OSErr err;
-
- if (pFilePB->ioParam.ioResult != noErr) {
- sprintf(debugStr, "Error in write to file: %hd", pFilePB->ioParam.ioResult);
- FWDebugStr((ConstStr255Param) c2pstr (debugStr));
- }
-
- pFilePB->ioParam.ioTrap = kFWXRead;
- pFilePB->ioParam.ioCompletion = (IOCompletionUPP) HandleFWReadComplete;
- pFilePB->ioParam.ioReqCount = kFWReadDataBufSize;
- pFilePB->ioParam.ioMisc = (Ptr) kForkData;
-
- err = CallFWXNode((IOParamPtr) pFilePB);
- if (err != noErr) {
- sprintf(debugStr, "Error in CallFWXNode, FileWriteComplete: %d", err);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
-
- return (noErr);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleFolderInfo
- //
- // Writes the finder catalog info for the folder
- //
- static OSErr HandleFolderInfo(
- CInfoPBPtr pCatInfoPB,
- SInt32 dirID)
- {
- OSErr err;
-
- pCatInfoPB->dirInfo.ioFDirIndex = 0; // use ioDirID
- pCatInfoPB->dirInfo.ioVRefNum = gpFWXAppData->fwixReceiveFolder.vRefNum;
- pCatInfoPB->dirInfo.ioDrDirID = dirID;
- pCatInfoPB->dirInfo.ioNamePtr = nil;
-
- err = PBSetCatInfoSync(pCatInfoPB);
-
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // HandleFileInfo
- //
- // Writes the finder info for the file
- //
- static OSErr HandleFileInfo(
- FSSpecPtr pNewFileSpec,
- CInfoPBPtr pCatInfoPB)
- {
- OSErr err;
-
- pCatInfoPB->hFileInfo.ioFDirIndex = 0; // use ioNamePtr and ioDirID
- pCatInfoPB->hFileInfo.ioVRefNum = pNewFileSpec->vRefNum;
- pCatInfoPB->hFileInfo.ioDirID = pNewFileSpec->parID;
- pCatInfoPB->hFileInfo.ioNamePtr = pNewFileSpec->name;
-
- // don't copy the hasBeenInited bit */
- pCatInfoPB->hFileInfo.ioFlFndrInfo.fdFlags =
- pCatInfoPB->hFileInfo.ioFlFndrInfo.fdFlags & 0xfeff;
-
- err = PBSetCatInfoSync(pCatInfoPB);
-
- /****
- * Some idea of how to take care of file lock
- * what about comments? custom icons? JKL****
- *
- if ((err == noErr) && (copyLockBit) && (pCatInfoPB->hFileInfo.ioFlAttrib & 0x01) != 0))
- {
- pb.hPB.fileParam.ioFVersNum = 0;
- error = PBHSetFLockSync(&pb.hPB);
- if ( (error != noErr) && (objectIsDirectory) )
- error = noErr; // ignore lock errors if destination is directory
- }
- *
- ****/
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // CleanupCopyDialog
- //
- // Destroys the copy dialog
- //
- void CleanupCopyDialog(
- WindowPtr theDialog)
- {
- Handle item;
- Rect box;
- SInt16 itemType;
-
- GetDialogItem(theDialog, kProgressBarUserItem, &itemType, &item, &box);
- DisposeRoutineDescriptor((UserItemUPP) item);
- DisposeDialog(theDialog);
- EnableItem(GetMenuHandle(kFileMenuID), 0);
- EnableItem(GetMenuHandle(kEditMenuID), 0);
- EnableItem(GetMenuHandle(kViewMenuID), 0);
- DrawMenuBar();
- gBytesToCopy = 0;
- gItemsToCopy = 0;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // DisplayCopyDialog
- //
- // Creates the copy dialog
- //
- static OSErr DisplayCopyDialog (void)
- {
- DialogPtr pDialog;
- UserItemUPP pUserDrawProc;
- Handle item;
- Rect box;
- SInt16 itemType;
- OSErr err = noErr;
-
- pUserDrawProc = NewUserItemProc(DrawProgressBar);
- if (pUserDrawProc == nil)
- return memFullErr;
-
- pDialog = GetNewDialog(kCopyProgressDlog, nil, (WindowPtr) -1);
- if (pDialog != nil) {
- // get handle to progress bar user item and replace with draw proc
- GetDialogItem(pDialog, kProgressBarUserItem, &itemType, &item, &box);
- SetDialogItem(pDialog, kProgressBarUserItem, itemType,
- (Handle) pUserDrawProc, &box);
- ShowWindow(pDialog);
- } else
- err = ResError();
-
- DisableItem(GetMenuHandle(kFileMenuID), 0);
- DisableItem(GetMenuHandle(kEditMenuID), 0);
- DisableItem(GetMenuHandle(kViewMenuID), 0);
- DrawMenuBar();
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // DrawProgressBar
- //
- // Draws progress bar in copy dialog
- //
- pascal void DrawProgressBar(
- WindowPtr theWindow,
- SInt16 itemNo)
- {
- WindowPtr curPort;
- Handle item;
- Rect box;
- RGBColor curColor;
- RGBColor paintColor;
- unsigned char s[8];
- float rightVal;
- SInt16 itemType;
-
- GetDialogItem(theWindow, itemNo, &itemType, &item, &box);
- GetPort(&curPort);
- SetPort(theWindow);
-
- FrameRect(&box);
-
- InsetRect(&box, 1, 1);
- GetForeColor(&curColor);
- paintColor.red = 40000;
- paintColor.blue = 45000;
- paintColor.green = 40000;
- RGBForeColor(&paintColor);
- PaintRect(&box);
-
- rightVal = (float) gBytesCopied / (float) gBytesToCopy;
- box.right = rightVal * 200.0 + box.left;
- paintColor.red = 10000;
- paintColor.blue = 15000;
- paintColor.green = 10000;
- RGBForeColor(&paintColor);
- PaintRect(&box);
-
- RGBForeColor(&curColor);
-
- MoveTo(167, 22);
- NumToString(gItemsToCopy, s);
- DrawString((ConstStr255Param) s);
-
- if (gSendQHdr.qHead != nil)
- {
- MoveTo(94, 47);
- DrawString(((TxFSSpecPtr) gSendQHdr.qHead)->pFSSpec->name);
- }
-
- SetPort(curPort);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // UpdateProgressBar
- //
- // Advances progress bar to show copy status
- //
- void UpdateProgressBar (
- WindowPtr theWindow,
- SInt16 itemNo)
- {
- WindowPtr curPort;
- Handle item;
- Rect box;
- RGBColor curColor;
- RGBColor paintColor;
- static UInt32 lastCopyCount = 0;
- unsigned char s[8];
- float rightVal;
- SInt16 itemType;
-
- GetDialogItem(theWindow, itemNo, &itemType, &item, &box);
- GetPort(&curPort);
- SetPort(theWindow);
-
- InsetRect(&box, 1, 1);
- GetForeColor(&curColor);
-
- rightVal = (float) gBytesCopied / (float) gBytesToCopy;
- box.right = rightVal * 200.0 + box.left;
- paintColor.red = 10000;
- paintColor.blue = 15000;
- paintColor.green = 10000;
- RGBForeColor(&paintColor);
- PaintRect(&box);
-
- RGBForeColor(&curColor);
-
- if (lastCopyCount != gItemsToCopy) {
- SetRect(&box, 166, 10, 320, 27);
- EraseRect(&box);
- MoveTo(167, 22);
- NumToString(gItemsToCopy, s);
- DrawString((ConstStr255Param) s);
-
- SetRect(&box, 93, 35, 320, 52);
- EraseRect(&box);
- MoveTo(94, 47);
- DrawString(((TxFSSpecPtr) gSendQHdr.qHead)->pFSSpec->name);
-
- lastCopyCount = gItemsToCopy;
- }
-
- SetPort(curPort);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // FSpGetCatInfo
- //
- // Utility routine to call PBGetCatInfo using file system spec
- //
-
- OSErr FSpGetCatInfo(
- FSSpec *pFSSpec,
- CInfoPBPtr pCatInfoPB)
- {
- pCatInfoPB->hFileInfo.ioFDirIndex = 0;
- pCatInfoPB->hFileInfo.ioDirID = pFSSpec->parID;
- pCatInfoPB->hFileInfo.ioVRefNum = pFSSpec->vRefNum;
- pCatInfoPB->hFileInfo.ioNamePtr = pFSSpec->name;
-
- return PBGetCatInfoSync(pCatInfoPB);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // GetItemSize
- //
- // Calculate size of item.
- //
- OSErr GetItemSize(
- NodeSendItemPtr pSendItem)
- {
- CInfoPBRec catInfo;
- UInt32 itemCount;
- OSErr err;
- Boolean isFile;
-
- pSendItem->itemSize = 0;
- itemCount = 0;
- err = FSpGetCatInfo(&pSendItem->sendItemSpec, &catInfo);
-
- itemCount++;
- isFile = !(catInfo.dirInfo.ioFlAttrib & ioDirMask);
- if (isFile)
- {
- pSendItem->itemSize += catInfo.hFileInfo.ioFlLgLen;
- pSendItem->itemSize += catInfo.hFileInfo.ioFlRLgLen;
- }
- else
- {
- err = CalcDirectorySize (catInfo.dirInfo.ioDrDirID,
- pSendItem->sendItemSpec.vRefNum,
- &pSendItem->itemSize,
- &itemCount);
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // CountCopyData
- //
- // Tally items to be copied.
- //
- OSErr CountCopyData(
- FSSpec *pFSSpec)
- {
- CInfoPBRec catInfo;
- OSErr err;
- Boolean isFile;
-
- err = FSpGetCatInfo(pFSSpec, &catInfo);
- if (err == noErr)
- {
- gItemsToCopy++;
- isFile = !(catInfo.dirInfo.ioFlAttrib & ioDirMask);
- if (isFile)
- {
- gBytesToCopy += catInfo.hFileInfo.ioFlLgLen;
- gBytesToCopy += catInfo.hFileInfo.ioFlRLgLen;
- }
- else
- {
- err = CalcDirectorySize (catInfo.dirInfo.ioDrDirID,
- pFSSpec->vRefNum,
- &gBytesToCopy,
- &gItemsToCopy);
- }
- }
- return err;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // CalcDirectorySize
- //
- // Traverse a directory finding each of its items. If an item in a directory
- // is also a directory, recurse to find all of its items. It an item is a
- // file add its size to the byte count.
- //
-
- static OSErr CalcDirectorySize (
- SInt32 dirID,
- SInt16 vRefNum,
- UInt32 *dirSize,
- UInt32 *dirItems)
- {
- SInt16 index;
- OSErr err = noErr;
- Boolean isFile;
-
- gCatInfoPB.hFileInfo.ioVRefNum = vRefNum;
-
- for (index = 1; ; index++)
- {
- // reset the directory id after each call to PBGetCatInfo
- gCatInfoPB.hFileInfo.ioDirID = dirID;
- gCatInfoPB.hFileInfo.ioFDirIndex = index;
-
- err = PBGetCatInfoSync(&gCatInfoPB);
- if (err != noErr)
- {
- // returns file not found when directory has been traversed
- if (err == fnfErr)
- err = noErr;
- break;
- }
- *dirItems = *dirItems + 1;
- isFile = !(gCatInfoPB.dirInfo.ioFlAttrib & ioDirMask);
- if (isFile)
- {
- *dirSize += gCatInfoPB.hFileInfo.ioFlLgLen;
- *dirSize += gCatInfoPB.hFileInfo.ioFlRLgLen;
- }
- else
- {
- err = CalcDirectorySize (gCatInfoPB.dirInfo.ioDrDirID,
- vRefNum,
- dirSize,
- dirItems);
- }
- }
- return err;
-
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SetupFileReadPB
- //
- // Zero out unused fields and set used fields
- //
-
- void SetupFileReadPB(
- IOParamPtr pb)
- {
- pb->ioCompletion = gpFWXAppData->fileReadCompletionHandler;
- pb->ioRefNum = gCurForkRefNum;
- pb->ioReqCount = kFileReadBufSize;
- pb->ioPosMode = fsAtMark + 0x0020;
-
- pb->qLink = nil;
- pb->qType = 0;
- pb->ioTrap = 0;
- pb->ioCmdAddr = nil;
- pb->ioResult = noErr;
- pb->ioNamePtr = nil;
- pb->ioVRefNum = 0;
- pb->ioVersNum = 0;
- pb->ioPermssn = 0;
- pb->ioMisc = nil;
- pb->ioActCount = 0;
- pb->ioPosOffset = 0;
-
- // pb->ioBuffer // set by init routine
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SetupFWWritePB
- //
- // Zero out unused fields and set used fields
- //
-
- void SetupFWWritePB(
- IOParamPtr pb)
- {
- pb->ioCompletion = (IOCompletionUPP) HandleFWWriteComplete;
- pb->ioNamePtr = (StringPtr) ((TxFSSpecPtr) gSendQHdr.qHead)->recvNode;
- pb->ioTrap = kFWXWrite;
-
- pb->qLink = nil;
- pb->qType = 0;
- pb->ioCmdAddr = nil;
- pb->ioResult = noErr;
- pb->ioVRefNum = 0;
- pb->ioVersNum = 0;
- pb->ioPermssn = 0;
- pb->ioActCount = 0;
- pb->ioPosMode = 0;
- pb->ioPosOffset = 0;
-
- // pb->ioMisc // set by routine doing the write
- // pb->ioBuffer // set by init routine
- // pb->ioReqCount // set by routine doing the write
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SetupFWControlPB
- //
- // Zero out unused fields and set used fields
- //
-
- void SetupFWControlPB(
- IOParamPtr pb)
- {
- pb->ioCompletion = (IOCompletionUPP) HandleFWControlComplete;
- pb->ioNamePtr = (StringPtr) ((TxFSSpecPtr) gSendQHdr.qHead)->recvNode;
- pb->ioTrap = kFWXWrite;
-
- pb->qLink = nil;
- pb->qType = 0;
- pb->ioCmdAddr = nil;
- pb->ioResult = noErr;
- pb->ioVRefNum = 0;
- pb->ioVersNum = 0;
- pb->ioPermssn = 0;
- pb->ioActCount = 0;
- pb->ioPosMode = 0;
- pb->ioPosOffset = 0;
-
- // pb->ioMisc // set by routine doing the write
- // pb->ioBuffer // set by init routine
- // pb->ioReqCount // set by routine doing the write
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // FWIXDequeue
- //
- // Reentrant safe dequeue.
- //
-
- OSErr FWIXDequeue(
- QElemPtr *ppQElem,
- QHdrPtr pQHdr)
- {
- QElemPtr pQElem;
- OSErr err = noErr;
-
- // Attempt to dequeue element at head of queue.
- pQElem = pQHdr->qHead;
- if (pQElem != nil)
- err = Dequeue (pQElem, pQHdr);
-
- // If we failed, try again until we get an element or none are left
- // in queue.
- while ((pQElem != nil) && (err != noErr))
- {
- pQElem = pQHdr->qHead;
- if (pQElem != nil)
- err = Dequeue (pQElem, pQHdr);
- }
-
- // Return results.
- if (err == noErr)
- *ppQElem = pQElem;
- else
- *ppQElem = nil;
-
- return (err);
- }